package co.com.smart.persistence.entity;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import javax.ejb.Stateless;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import co.com.smart.maestro.infraestructure.dto.ExcepcionDTO;
import co.com.smart.maestro.infraestructure.dto.ExcepcionDTO.Tipo;
import co.com.smart.maestro.infraestructure.dto.MensajeSQLDTO;
import co.com.smart.maestro.infraestructure.dto.ResponseJson;
import co.com.smart.persistence.entity.dto.DocenteOBJ;
import co.com.smart.persistence.entity.util.AbstractFacade;
import co.com.smart.session.DelegateContextEJB;
import co.com.smart.utilidades.Constantes;


@Stateless(
		name		= "DocentesFacade", 
		mappedName 	= "ejb/DocentesFacade")
public class DocenteFacade extends AbstractFacade<DocenteOBJ> implements DocenteFacadeLocal {


	@PersistenceContext(unitName = "SmartServicesPU")
	private EntityManager em;

	private HashMap<String,MensajeSQLDTO> errores;

	public DocenteFacade() {
		super(DocenteOBJ.class);
		errores = new HashMap<String,MensajeSQLDTO>();
		errores.put("1062", new MensajeSQLDTO("DUPLICATE_KEY_FOUND"     , "Registros duplicados"));
		errores.put("1216", new MensajeSQLDTO("CHILD_RECORD_FOUND"      , "Registros duplicados"));
		errores.put("1217", new MensajeSQLDTO("PARENT_RECORD_NOT_FOUND" , "Registros duplicados"));
		errores.put("1048", new MensajeSQLDTO("NULL_VALUE_FOUND"        , "Registros duplicados"));
		errores.put("1205", new MensajeSQLDTO("RECORD_HAS_BEEN_LOCKED"  , "Registros duplicados"));
	}

	@Override
	protected EntityManager getEntityManager() {
		return em;
	}

	@Override
	public ResponseJson crearDocente(DocenteOBJ docente) throws ExcepcionDTO {
		ResponseJson retorno = new ResponseJson();
		DocenteFacadeLocal servicio;
		
		try {
			servicio = DelegateContextEJB.getDocentesFacadeLocal();
			servicio.create(docente);
			retorno.setCodigo(Constantes.StatusResponse.OK.getStatus());
			retorno.setMensaje("Registro insertado con exito");
		}catch(PersistenceException e) {
			MensajeSQLDTO sqlError = getErrorCode(e);
			ExcepcionDTO excepcion = new ExcepcionDTO();
			excepcion.setMensaje(sqlError.getDescripcion());
			excepcion.setTipo(Tipo.ERROR);
			throw excepcion;
		}catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return retorno;
	}

	protected MensajeSQLDTO getErrorCode(RuntimeException e) {
		Throwable throwable 	= e;
		MensajeSQLDTO res	= new MensajeSQLDTO("NONE","Proceso exitoso");
		while (throwable != null && !(throwable instanceof SQLException)) {
			throwable 			= throwable.getCause();
		}
		if(throwable instanceof SQLException) {
			SQLException sqlex 	= (SQLException) throwable;
			res 					= errores.get(sqlex.getErrorCode() + "");
		}
		return res;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<DocenteOBJ> consultarDocentes(
			String nombre, 
			String apellido, 
			String documento) 
			{
		String SQL_STR		= "SELECT o FROM DocenteOBJ as o WHERE 1 = 1";

		if(nombre    != null) {
			SQL_STR			= SQL_STR + " AND fnombre = :fnombre";	
		}
		if(apellido  != null) {
			SQL_STR			= SQL_STR + " AND fapellido = :fapellido";	
		}
		if(documento != null) {
			SQL_STR			= SQL_STR + " AND fdocumento = :fdocumento";	
		}

		StringBuilder sql 	= new StringBuilder(SQL_STR);
		Query query 		= em.createQuery(sql.toString());

		if(SQL_STR.indexOf(":fnombre") > 0)    {
			query.setParameter("fnombre"    , nombre);
		}
		if(SQL_STR.indexOf(":fapellido") > 0)  {
			query.setParameter("fapellido"  , apellido);
		}
		if(SQL_STR.indexOf(":fdocumento") > 0) {
			query.setParameter("fdocumento" , documento);		
		}

		return query.getResultList();
			}

	@Override
	public ResponseJson editDocente(DocenteOBJ docente) throws ExcepcionDTO {
		ResponseJson retorno = new ResponseJson();
		DocenteFacadeLocal servicio;
		
		try {
			servicio = DelegateContextEJB.getDocentesFacadeLocal();
			servicio.edit(docente);
			retorno.setCodigo(Constantes.StatusResponse.OK.getStatus());
			retorno.setMensaje("Registro actualizado con exito");
		}catch(PersistenceException e) {
			MensajeSQLDTO sqlError = getErrorCode(e);
			ExcepcionDTO excepcion = new ExcepcionDTO();
			excepcion.setMensaje(sqlError.getDescripcion());
			excepcion.setTipo(Tipo.ERROR);
			throw excepcion;
		}catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return retorno;
	}
	
	@Override
	public ResponseJson removeDocente(DocenteOBJ docente) throws ExcepcionDTO {
		
		ResponseJson retorno = new ResponseJson();
		DocenteFacadeLocal servicio;
		
		try {
			servicio = DelegateContextEJB.getDocentesFacadeLocal();
			servicio.remove(docente);
			retorno.setCodigo(Constantes.StatusResponse.OK.getStatus());
			retorno.setMensaje("Registro eliminado con exito");
		}catch(PersistenceException e) {
			MensajeSQLDTO sqlError = getErrorCode(e);
			ExcepcionDTO excepcion = new ExcepcionDTO();
			excepcion.setMensaje(sqlError.getDescripcion());
			excepcion.setTipo(Tipo.ERROR);
			throw excepcion;
		}catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return retorno;
		
	}

}
